﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using ReportWizard.Comparers;
using ReportWizard.DataAccess;
using ReportWizard.Helpers;
using ReportWizard.Properties;
using Shortcut = ReportWizard.Helpers.Shortcut;

namespace ReportWizard.Forms
{
    public partial class SettingsForm : IconForm
    {
        private WordTemplate SelectedTemplate { get; set; }
        
        private int SelectedUserId { get; set; }

        private List<UserInfo> _listUsers;
        
        public SettingsForm()
        {
            InitializeComponent();

            ShowCustomRightButton = false;
            ShowCustomLeftButton = false;
            ShowCheckFooter = false;
        }

        private void SettingsFormLoad(object sender, EventArgs e)
        {
            HeaderText = Resources.ProfileSettings;
            ilBookmarks.Images.Add(Resources.Bookmark_icon);

            dgvTemplates.AutoGenerateColumns = false;
            dgvUsers.AutoGenerateColumns = false;

            FillPerferences();
            FillTemplateList();
            FillProfileInfo();
            FillUserList();

            CheckAdmin();
        }

        #region Templates

        private void ClearTemplateTab()
        {
            tbTemplatePath.Text = string.Empty;
            tbTemplatePath.Tag = null;

            tbTemplateDescription.Text = string.Empty;
        }

        private void ClearTemplateForm()
        {
            dgvTemplates.DataSource = null;
            comboTempalteSelect.DataSource = null;
            SelectedTemplate = null;
            lvTemplateBookmarks.Items.Clear();
            lTextBookmarksCountValue.Text =
                lPhotoBookmarksCountValue.Text =
                lBookmarkGroupsCountValue.Text =
                lTemplateNameValue.Text = Resources.DefaultTemplateInfoCountValue;
        }

        private void FillTemplateList()
        {
            ClearTemplateForm();

            List<WordTemplate> wtList = WordTemplate.Select(false);
            if (wtList != null)
            {
                dgvTemplates.DataSource = wtList;
                comboTempalteSelect.DataSource = wtList;
            }
        }

        private void FillTemplateInfo()
        {
            if (SelectedTemplate != null)
            {
                lTemplateNameValue.Text = SelectedTemplate.FileName;

                lvTemplateBookmarks.Items.Clear();
                List<WordBookmark> wordBookmarks = WordBookmark.Select(SelectedTemplate.Id, true);
                List<BookmarkGroup> bookmarkGroups = BookmarkGroup.SelectInTemplate(SelectedTemplate.Id);

                lTextBookmarksCountValue.Text = wordBookmarks != null
                                                    ? wordBookmarks.Where(
                                                        i => i.IsTextBookmark && i.BookmarkGroupId == 0).
                                                          Count().ToString()
                                                    : "0";

                lPhotoBookmarksCountValue.Text = wordBookmarks != null
                                                     ? wordBookmarks.Where(i => !i.IsTextBookmark).Count().ToString()
                                                     : "0";

                lBookmarkGroupsCountValue.Text = bookmarkGroups != null ? bookmarkGroups.Count.ToString() : "0";

                if (wordBookmarks != null)
                {
                    for (int i = 0; i < wordBookmarks.Count; i++)
                    {
                        lvTemplateBookmarks.Items.Add(wordBookmarks[i].Name.Replace('_', ' '), 0);
                    }
                }
            }
        }

        private void BTemplateOpenClick(object sender, EventArgs e)
        {
            if (dlgTemplate.ShowDialog() == DialogResult.OK)
            {
                tbTemplatePath.Text = Path.GetFileName(dlgTemplate.FileName);
                tbTemplatePath.Tag = dlgTemplate.FileName;
                ttSettings.SetToolTip(tbTemplatePath, dlgTemplate.FileName);
            }
        }

        private void BTemplateLoadClick(object sender, EventArgs e)
        {
            if (tbTemplatePath.Tag != null && File.Exists(tbTemplatePath.Tag.ToString()))
            {
                try
                {
                    List<string> docBookmarks = MsWord.GetBookmarks(tbTemplatePath.Tag.ToString());
                    if (docBookmarks != null)
                    {
                        WordTemplate wt = new WordTemplate(File.ReadAllBytes(tbTemplatePath.Tag.ToString()), tbTemplatePath.Text, tbTemplateDescription.Text.Trim(), checkTemplateVisible.Checked);

                        wt.Insert();
                        if (wt.Id != 0)
                        {
                            bool parseImageTags = Perferences.ParseImageTags;

                            wt.DocumentBookmarks = new List<WordBookmark>();
                            for (int i = 0; i < docBookmarks.Count; i++)
                            {
                                WordBookmark wb = new WordBookmark
                                                        {
                                                            WordTemplateId = wt.Id,
                                                            Name = docBookmarks[i],
                                                            Visible = true,
                                                            IsTextBookmark = !parseImageTags || !docBookmarks[i].StartsWith(Resources.BookmarkImagePrefix)
                                                        };
                                wt.DocumentBookmarks.Add(wb);
                                wb.Insert();
                            }
                            FillTemplateList();

                            if (Perferences.GroupSameTags)
                            {
                                var groupingBookmarks =
                                    wt.DocumentBookmarks.Where(i => i.Name.Contains(Resources.BookmarkGroupSeparator)).ToList();

                                var groupingBookmarksNames =
                                    groupingBookmarks.GroupBy(
                                        i => i.Name.Substring(0, i.Name.IndexOf(Resources.BookmarkGroupSeparator)));
                                foreach (IGrouping<string, WordBookmark> wordBookmarks in groupingBookmarksNames)
                                {
                                    SetFileNameForm sf = new SetFileNameForm(true)
                                    {
                                        FormCaption = Resources.CommonNameForBookmarkGroup,
                                        Text = Resources.GrouppingBookmarks
                                    };
                                    sf.ShowDialog();

                                    BookmarkGroup bg = new BookmarkGroup
                                    {
                                        Name = sf.NewName
                                    };
                                    bg.Insert();

                                    if (bg.Id != 0)
                                    {
                                        foreach (WordBookmark wordBookmark in groupingBookmarks)
                                        {
                                            if (wordBookmark.Name.Contains(Resources.BookmarkGroupSeparator) &&
                                                wordBookmark.Name.StartsWith(wordBookmarks.Key))
                                            {
                                                wordBookmark.BookmarkGroupId = bg.Id;
                                                wordBookmark.Update();
                                            }
                                        }
                                    }
                                }
                            }
                            
                            EditBookmarksForm ebf = new EditBookmarksForm(wt);
                            if (ebf.ShowDialog() == DialogResult.OK)
                            {
                                FillTemplateList();
                            }
                                
                            ClearTemplateTab();
                        }
                        
                    }
                    else
                    {
                        ShowMessage.Error(Resources.NoBookmarksInDocument);
                    }

                }
                catch (Exception ex)
                {
                    Logger.WriteLog(ex);
                }
            }
            else
            {
                ShowMessage.Error(Resources.SpecifyPathToTemplate);
            }
        }

        private void BTemplateClearClick(object sender, EventArgs e)
        {
            ClearTemplateTab();
        }

        private void DgvTemplatesRowEnter(object sender, DataGridViewCellEventArgs e)
        {
            if (dgvTemplates.Rows[e.RowIndex].Cells["dgvcId"].Value != null)
            {
                SelectedTemplate = WordTemplate.Select(Convert.ToInt32(dgvTemplates.Rows[e.RowIndex].Cells["dgvcId"].Value));
                
                FillTemplateInfo();
            }
        }

        private void TemplateEditClick(object sender, EventArgs e)
        {
            if (SelectedTemplate != null)
            {
                EditBookmarksForm ebf = new EditBookmarksForm(WordTemplate.Select(SelectedTemplate.Id));
                if (ebf.ShowDialog() == DialogResult.OK)
                {
                    FillTemplateList();
                }
            }
        }

        private void MiTemplateDeleteClick(object sender, EventArgs e)
        {
            if (SelectedTemplate != null)
            {
                WordTemplate wt = WordTemplate.Select(SelectedTemplate.Id);
                if (wt != null)
                {
                    if (MessageBox.Show(string.Format("{0} {1} ?", Resources.DeleteTemplate, wt.FileName), Resources.TitleDelete, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
                    {
                        if (WordTemplate.Delete(SelectedTemplate.Id))
                        {
                            FillTemplateList();
                        }
                    }
                }
            }
        }

        #endregion

        #region Perferences

        private void FillPerferences()
        {
            tbConfigTemplatePath.Text = Perferences.PathTemplateFile;
            tbConfigReportPath.Text = Perferences.PathReportFile;
            tbConfigLogPath.Text = Perferences.PathLogFile;
            tbConfigGamePath.Text = Perferences.PathGame;
            checkParseTagImage.Checked = Perferences.ParseImageTags;
            checkGroupSameTags.Checked = Perferences.GroupSameTags;
            checkViewPhotoListAsThumbnails.Checked = Perferences.ViewPhotoListAsThumbnails;
        }

        private void DlgFolderPathOpen(object sender, EventArgs e)
        {
            if (dlgFolderPath.ShowDialog() == DialogResult.OK)
            {
                if (((Button)sender).Tag != null)
                {
                    tlpPathLayout.Controls[((Button) sender).Tag.ToString()].Text = dlgFolderPath.SelectedPath;
                }
            }
        }

        private void DlgPathToGame(object sender, EventArgs e)
        {
            if (dlgGame.ShowDialog() == DialogResult.OK)
            {
                tbConfigGamePath.Text = dlgGame.FileName;
            }
        }

        private void SavePerferences()
        {
            Perferences.SetPerferenceValue(ToolPerferences.PathTemplateFile, tbConfigTemplatePath.Text);
            Perferences.SetPerferenceValue(ToolPerferences.PathReportFile, tbConfigReportPath.Text);
            Perferences.SetPerferenceValue(ToolPerferences.PathLogFile, tbConfigLogPath.Text);
            Perferences.SetPerferenceValue(ToolPerferences.PathGame, tbConfigGamePath.Text);
            Perferences.SetPerferenceValue(ToolPerferences.ParseImageTags, checkParseTagImage.Checked.ToString());
            Perferences.SetPerferenceValue(ToolPerferences.GroupSameTags, checkGroupSameTags.Checked.ToString());
            Perferences.SetPerferenceValue(ToolPerferences.ViewPhotoListAsThumbnails, checkViewPhotoListAsThumbnails.Checked.ToString());
        }

        private void DefaultPerferencesClick(object sender, EventArgs e)
        {
            if (MessageBox.Show(Resources.SaveDefaultPathSettings, Resources.TitleWarning, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1) == DialogResult.OK)
            {
                Shortcut.Create();
                Perferences.CreateDefaultPerferences();
            }
        }

        #endregion

        #region Profile

        private void FillProfileInfo()
        {
            if (Globals.CurrentUser != null)
            {
                lProfileDateCreated.Text = string.Format("Дата регистрации: {0}", Globals.CurrentUser.DateCreated.ToShortDateString());
                tbProfileFirstName.Text = Globals.CurrentUser.FirstName;
                tbProfileLastName.Text = Globals.CurrentUser.LastName;
                tbProfileLogin.Text = Globals.CurrentUser.Login;
                checkProfileAdmin.Checked = Globals.CurrentUser.Admin;
                checkProfileActive.Checked = Globals.CurrentUser.Active;
            }
        }

        private bool UpdateUserInfo()
        {
            Globals.CurrentUser.FirstName = tbProfileFirstName.Text.Trim();
            Globals.CurrentUser.LastName = tbProfileLastName.Text.Trim();
            Globals.CurrentUser.Login = tbProfileLogin.Text.Trim();
            Globals.CurrentUser.Admin = checkProfileAdmin.Checked;
            Globals.CurrentUser.Active = checkProfileActive.Checked;

            string oldPass = tbProfileOldPassword.Text;
            string newPass1 = tbProfileNewPassword.Text;
            string newPass2 = tbProfileRepeatNewPassword.Text;

            if (!string.IsNullOrEmpty(oldPass) || !string.IsNullOrEmpty(newPass1) || !string.IsNullOrEmpty(newPass2))
            {
                if (!string.IsNullOrEmpty(oldPass) && Crypto.GetMd5Sum(oldPass).Equals(Globals.CurrentUser.Password))
                {
                    if (!string.IsNullOrEmpty(newPass1) && !string.IsNullOrEmpty(newPass2))
                    {
                        if (newPass1.Equals(newPass2))
                        {
                            Globals.CurrentUser.Password = newPass1;
                            return Globals.CurrentUser.Update();
                        }
                        else
                        {
                            ShowMessage.Error(Resources.NewPasswordIncorrectRepeated);
                            return false;
                        }
                    }
                    else
                    {
                        ShowMessage.Error(Resources.TypeAndRepeatNewPassword);
                        return false;
                    }
                }
                else
                {
                    ShowMessage.Error(Resources.OldPasswordIsIncorrect);
                    return false;
                }
            }
            else
            {
                return Globals.CurrentUser.Update();
            }
        }

        #endregion

        #region Users

        private void FillUserList()
        {
            dgvUsers.DataSource = null;
            comboUserSelect.DataSource = null;

            _listUsers = UserInfo.Select();
            if (_listUsers != null)
            {
                dgvUsers.DataSource = _listUsers;
                comboUserSelect.DataSource = _listUsers;
                comboUserSelect.DisplayMember = "Login";
                comboUserSelect.ValueMember = "Id";
            }
        }

        private void UserAddClick(object sender, EventArgs e)
        {
            EditUserInfoForm addUserForm = new EditUserInfoForm();
            if (addUserForm.ShowDialog() == DialogResult.OK)
            {
                FillUserList();
            }
        }

        private void UserEditClick(object sender, EventArgs e)
        {
            Point dgvArchiveAreaPoint = dgvUsers.PointToClient(Cursor.Position);
            DataGridView.HitTestInfo dgvUsersArea = dgvUsers.HitTest(dgvArchiveAreaPoint.X, dgvArchiveAreaPoint.Y);

            //if (dgvArchiveArea.Type == DataGridViewHitTestType.Cell && SelectedReportId > 0)

            if (dgvUsers.SelectedRows.Count != 0 && (sender is ToolStripItem || dgvUsersArea.Type == DataGridViewHitTestType.Cell))
            {
                EditUserInfoForm editUserForm = new EditUserInfoForm(SelectedUserId);
                if (editUserForm.ShowDialog() == DialogResult.OK)
                {
                    if (SelectedUserId.Equals(Globals.CurrentUser.Id))
                    {
                        FillProfileInfo();
                    }
                    FillUserList();
                }
            }
        }

        private void DgvUsersRowEnter(object sender, DataGridViewCellEventArgs e)
        {
            if (dgvUsers.Rows[e.RowIndex].Cells["dgvcUserId"].Value != null)
            {
                SelectedUserId = Convert.ToInt32(dgvUsers.Rows[e.RowIndex].Cells["dgvcUserId"].Value);
            }
        }

        private void UserDeleteClick(object sender, EventArgs e)
        {
            if (SelectedUserId > 0)
            {
                if (
                    MessageBox.Show(string.Format("Удалить пользователя {0}?", UserInfo.Select(SelectedUserId)),
                                    Resources.Deleting, MessageBoxButtons.OKCancel, MessageBoxIcon.Question,
                                    MessageBoxDefaultButton.Button1) == DialogResult.OK)
                {
                    if (UserInfo.Delete(SelectedUserId))
                        FillUserList();
                }
            }
        }

        private void DgvUsersColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (_listUsers != null)
            {
                string dataPropertyName = dgvUsers.Columns[e.ColumnIndex].DataPropertyName;
                SortOrder strSortOrder = Digest.GetSortOrder(dgvUsers, e.ColumnIndex);
                dgvUsers.DataSource = null;

                _listUsers.Sort(
                    new UserInfoComparer(
                        (UserInfo.SortingFields)Enum.Parse(typeof(UserInfo.SortingFields), dataPropertyName),
                        strSortOrder));
                dgvUsers.DataSource = _listUsers;

                dgvUsers.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection = strSortOrder;
            }
        }

        #endregion

        private void CheckAdmin()
        {
            if (!Globals.CurrentUser.Admin)
            {
                tabSettings.TabPages.Remove(tabSettingsUsers);
                checkProfileAdmin.Enabled = false;
                checkProfileActive.Enabled = false;

                lConfigGamePath.Text = Resources.AllPathChangesOnlyForNewFiles;
                tlpPathLayout.SetRowSpan(lConfigGamePath, 2);

                bConfigGamePath.Visible = false;
                tbConfigGamePath.Visible = false;
            }
        }

        private void TabSettingsSelecting(object sender, TabControlCancelEventArgs e)
        {
            ShowCustomRightButton = (e.TabPage == tabSettingsCommon);
            ShowCustomLeftButton = (e.TabPage == tabSettingsUsers);

            if (e.TabPage == tabSettingsCommon)
            {
                HeaderText = Resources.CommonSettings;
            }
            else if (e.TabPage == tabSettingsProfile)
            {
                HeaderText = Resources.ProfileSettings;
            }
            else if (e.TabPage == tabSettingsTemplate)
            {
                HeaderText = Resources.WordTemplateSettings;
            }
            else if (e.TabPage == tabSettingsUsers)
            {
                HeaderText = Resources.UsersSettings;
            }
        }

        private void SavePerferencesClick(object sender, EventArgs e)
        {
            SavePerferences();
            if (UpdateUserInfo())
            {
                Close();
            }
            else
            {
                ShowMessage.Error(Resources.ErrorWhileSavingProfile);
            }
        }

        private void CancelClick(object sender, EventArgs e)
        {
            Close();
        }
        
    }
}
